﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using JBeamLibrary.Tools;
using JBeamLibrary.VehicleParts.Collections;
using JBeamLibrary.VehicleParts.Elements;
using JBeamLibrary.VehicleParts.Interfaces;

namespace JBeamLibrary.VehicleParts.Groups
{
    public class Beams : IVehicleGroup<Beam>
    {
        #region Fields

        private readonly Dictionary<int, BeamType> _beamTypeList = new Dictionary<int, BeamType>();
        private readonly Dictionary<int, long> _beamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, float> _beamPrecompressionList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _springExpansionList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _dampExpansionList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _beamLongBoundList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _beamShortBoundList = new Dictionary<int, float>();
        private readonly Dictionary<int, long> _beamLimitSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamLimitDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, float> _beamDampReboundList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _beamDampFastList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _beamDampReboundFastList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _beamDampVelocitySplitList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _pressureList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _surfaceList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _volumeCoefList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _maxPressureList = new Dictionary<int, float>();
        private readonly Dictionary<int, int> _breakgroupTypeList = new Dictionary<int, int>();
        private readonly Dictionary<int, string> _breakGroupList = new Dictionary<int, string>();
        private readonly Dictionary<int, string> _deformGroupList = new Dictionary<int, string>();
        private readonly Dictionary<int, float> _deformationTriggerRatioList = new Dictionary<int, float>();
        private readonly Dictionary<int, bool> _disableMeshBreakingList = new Dictionary<int, bool>();
        private readonly Dictionary<int, bool> _optionalList = new Dictionary<int, bool>();
        private readonly BeamCollection _collection = new BeamCollection();

        #endregion

        #region Indexers

        /// <summary>Gets the beam at the specified index</summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Beam this[int index]
        {
            get
            {
                if (Collection.Count == 0)
                    return null;
                if (index < 0 || index >= Collection.Count)
                    return null;
                return Collection[index];
            }
        }

        /// <summary>Gets the beam with the specified IDs</summary>
        /// <param name="id1"></param>
        /// /// <param name="id2"></param>
        /// <returns></returns>
        public Beam this[string id1, string id2]
        {
            get { return Collection.FirstOrDefault(beam => beam.NodeId1.Equals(id1) && beam.NodeId2.Equals(id2)); }
        }

        #endregion

        #region Properties

        public bool IsEmpty
        {
            get
            {
                return GroupHelper.GetPropertyLists(this).All(list => list.Count == 0) && Collection.Count == 0;
            }
        }

        public Dictionary<int, BeamType> BeamTypeList
        {
            get { return _beamTypeList; }
        }

        public Dictionary<int, long> BeamStrengthList
        {
            get { return _beamStrengthList; }
        }

        public Dictionary<int, long> BeamSpringList
        {
            get { return _beamSpringList; }
        }

        public Dictionary<int, long> BeamDampList
        {
            get { return _beamDampList; }
        }

        public Dictionary<int, long> BeamDeformList
        {
            get { return _beamDeformList; }
        }

        public Dictionary<int, float> BeamPrecompressionList
        {
            get { return _beamPrecompressionList; }
        }

        public Dictionary<int, float> SpringExpansionList
        {
            get { return _springExpansionList; }
        }

        public Dictionary<int, float> DampExpansionList
        {
            get { return _dampExpansionList; }
        }

        public Dictionary<int, float> BeamLongBoundList
        {
            get { return _beamLongBoundList; }
        }

        public Dictionary<int, float> BeamShortBoundList
        {
            get { return _beamShortBoundList; }
        }

        public Dictionary<int, long> BeamLimitSpringList
        {
            get { return _beamLimitSpringList; }
        }

        public Dictionary<int, long> BeamLimitDampList
        {
            get { return _beamLimitDampList; }
        }

        public Dictionary<int, float> BeamDampReboundList
        {
            get { return _beamDampReboundList; }
        }

        public Dictionary<int, float> BeamDampFastList
        {
            get { return _beamDampFastList; }
        }

        public Dictionary<int, float> BeamDampReboundFastList
        {
            get { return _beamDampReboundFastList; }
        }

        public Dictionary<int, float> BeamDampVelocitySplitList
        {
            get { return _beamDampVelocitySplitList; }
        }

        public Dictionary<int, float> PressureList
        {
            get { return _pressureList; }
        }

        public Dictionary<int, float> SurfaceList
        {
            get { return _surfaceList; }
        }

        public Dictionary<int, float> VolumeCoefList
        {
            get { return _volumeCoefList; }
        }

        public Dictionary<int, float> MaxPressureList
        {
            get { return _maxPressureList; }
        }

        public Dictionary<int, int> BreakgroupTypeList
        {
            get { return _breakgroupTypeList; }
        }

        public Dictionary<int, string> BreakGroupList
        {
            get { return _breakGroupList; }
        }

        public Dictionary<int, string> DeformGroupList
        {
            get { return _deformGroupList; }
        }

        public Dictionary<int, float> DeformationTriggerRatioList
        {
            get { return _deformationTriggerRatioList; }
        }

        public Dictionary<int, bool> DisableMeshBreakingList
        {
            get { return _disableMeshBreakingList; }
        }

        public Dictionary<int, bool> OptionalList
        {
            get { return _optionalList; }
        }

        public BeamCollection Collection
        {
            get { return _collection; }
        }

        public IVehicleGroupCollection<Beam> GroupCollection
        {
            get { return Collection; }
        }

        public int Count
        {
            get { return Collection.Count; }
        }

        #endregion

        #region Methods

        public void SetElementValue(int index, string propName, object value)
        {
            var elem = Collection[index];
            var prop = elem.GetType().GetProperty(propName);
            prop.SetValue(elem, value);
        }

        public object GetElementValue(int index, string propName)
        {
            var elem = Collection[index];
            var prop = elem.GetType().GetProperty(propName);
            return prop.GetValue(elem);
        }

        public IEnumerable<KeyValuePair<string, object>> GetElementValues(int index)
        {
            var elem = Collection[index];
            var props = elem.GetType().GetProperties();
            return props.Select(prop => new KeyValuePair<string, object>(prop.Name, prop.GetValue(elem))).AsEnumerable();
        }

        #endregion
    }
}
